/*
 * @Author: liu
 * @Date: 2024-03-07 00:06:57
 * @LastEditors: liu
 * @LastEditTime: 2024-04-11 00:34:18
 * @FilePath: \yyx_server_ts\app\controller\VodController.ts
 * @Description:阿里云视频点播相关接口
 * 天道酬勤
 */

import vod20170321, * as $vod20170321 from '@alicloud/vod20170321'
import OpenApi, * as $OpenApi from '@alicloud/openapi-client'
import Util, * as $Util from '@alicloud/tea-util'
import * as $tea from '@alicloud/tea-typescript'
import { Context } from 'koa'
import response from '../../utils/response'
import {
  GetVideoPlayerException,
  ParameterException,
  VideoUploadAuthException
} from '../exception/HttpException'

class Client {
  /**
   * 使用AK&SK初始化账号Client
   * @param accessKeyId
   * @param accessKeySecret
   * @return Client
   * @throws Exception
   */
  static createClient(
    accessKeyId: string,
    accessKeySecret: string
  ): vod20170321 {
    let config = new $OpenApi.Config({
      // 必填，您的 AccessKey ID
      accessKeyId: accessKeyId,
      // 必填，您的 AccessKey Secret
      accessKeySecret: accessKeySecret
    })
    // Endpoint 请参考 https://api.aliyun.com/product/vod
    config.endpoint = `vod.cn-shanghai.aliyuncs.com`
    return new vod20170321(config)
  }

  static async main(args: string[]): Promise<any> {
    // 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
    // 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取 AccessKey 的方式进行调用，仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378664.html
    let client = Client.createClient(
      process.env['ALIBABA_CLOUD_ACCESS_KEY_ID'] as string,
      process.env['ALIBABA_CLOUD_ACCESS_KEY_SECRET'] as string
    )
    let createUploadVideoRequest = new $vod20170321.CreateUploadVideoRequest({
      fileName: 'E:\v00.mp4',
      title: 'vod.mp4'
    })
    let runtime = new $Util.RuntimeOptions({})
    try {
      // 复制代码运行请自行打印 API 的返回值
      let res = await client.createUploadVideoWithOptions(
        createUploadVideoRequest,
        runtime
      )

      // console.log(res)
      return res
    } catch (error: any) {
      // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
      // 错误 message
      console.log(error.message)
      // 诊断地址
      console.log(error.data['Recommend'])
      Util.assertAsString(error.message)
    }
  }

  //返回数据文件名
  static getFilename(fileInfo: any) {
    let date = new Date()
    let time =
      '' +
      date.getFullYear() +
      '0' +
      (date.getMonth() + 1) +
      date.getDate() +
      date.getTime()

    let fileext = fileInfo.fileName.split('.').pop()
    let fileName = time + '.' + fileext

    return fileName
  }

  //1.获取视频上传凭证
  static async getUploadAuth(ctx: Context): Promise<any> {
    if (!ctx.request.body) {
      throw new ParameterException('', '参数错误！')
    }
    console.log(ctx.request.body)

    let fileInfo = ctx.request.body

    let fileName = Client.getFilename(fileInfo)

    // 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
    // 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取 AccessKey 的方式进行调用，仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378664.html
    let client = Client.createClient(
      process.env['ALIBABA_CLOUD_ACCESS_KEY_ID'] as string,
      process.env['ALIBABA_CLOUD_ACCESS_KEY_SECRET'] as string
    )

    let createUploadVideoRequest = new $vod20170321.CreateUploadVideoRequest({
      fileName: fileName,
      title: fileName
    })
    let runtime = new $Util.RuntimeOptions({})
    try {
      let res = await client.createUploadVideoWithOptions(
        createUploadVideoRequest,
        runtime
      )
      response.success(ctx, res.body, '获取视频上传凭证成功！')
    } catch (error: any) {
      // 诊断地址
      console.log(error.data['Recommend'])
      Util.assertAsString(error.message)
      throw new VideoUploadAuthException(error, error.message)
    }
  }

  //2.刷新视频上传凭证
  static async refreshUploadAuth(ctx: Context): Promise<any> {
    if (!ctx.request.body.uploadVideoId) {
      //   console.log(ctx.request.body)
      throw new ParameterException('', 'uploadVideId不能为空！')
    }

    let uploadVideoId = ctx.request.body.uploadVideoId

    try {
      let client = Client.createClient(
        process.env['ALIBABA_CLOUD_ACCESS_KEY_ID'] as string,
        process.env['ALIBABA_CLOUD_ACCESS_KEY_SECRET'] as string
      )

      let refreshUploadVideoRequest =
        new $vod20170321.RefreshUploadVideoRequest({
          videoId: uploadVideoId
        })

      let refreshUploadVideoReponse = await client.refreshUploadVideo(
        refreshUploadVideoRequest
      )

      response.success(
        ctx,
        refreshUploadVideoReponse.body,
        '刷新视频上传凭证成功！'
      )
    } catch (error: any) {
      // 诊断地址
      console.log(error.data['Recommend'])
      Util.assertAsString(error.message)
      throw new VideoUploadAuthException(error, error.message, 404)
    }
  }

  //3.获取视频上传详情
  static async getUploadDetails(ctx: Context) {
    if (!ctx.request.body.uploadVideoId) {
      //   console.log(ctx.request.body)
      throw new ParameterException('', 'uploadVideId不能为空！')
    }

    let uploadVideoId = ctx.request.body.uploadVideoId

    let client = Client.createClient(
      process.env['ALIBABA_CLOUD_ACCESS_KEY_ID'] as string,
      process.env['ALIBABA_CLOUD_ACCESS_KEY_SECRET'] as string
    )
    // console.log(uploadVideoId)
    let getUploadDetailsRequest = new $vod20170321.GetUploadDetailsRequest({
      mediaIds: uploadVideoId
    })

    let getUploadDetailsReponse = await client.getUploadDetails(
      getUploadDetailsRequest
    )

    response.success(
      ctx,
      getUploadDetailsReponse.body,
      '获取视频上传详情成功！'
    )
    //   return getUploadDetailsRequest
  }

  //媒体上传完成之后，可以获取媒体播放信息进行播放
  //4.通过播放地址播放
  static async getPlayAddres(ctx: Context): Promise<any> {
    if (!ctx.request.body.uploadVideoId) {
      //   console.log(ctx.request.body)
      throw new ParameterException('', 'uploadVideId不能为空！')
    }

    let uploadVideoId = ctx.request.body.uploadVideoId

    let client = Client.createClient(
      process.env['ALIBABA_CLOUD_ACCESS_KEY_ID'] as string,
      process.env['ALIBABA_CLOUD_ACCESS_KEY_SECRET'] as string
    )

    try {
      let getPlayInfoRequest = new $vod20170321.GetPlayInfoRequest({
        videoId: uploadVideoId
      })

      let getPlayInfoReponse = await client.getPlayInfo(getPlayInfoRequest)
      console.log(getPlayInfoReponse)
      response.success(ctx, getPlayInfoReponse.body, '获取播放地址成功！')
    } catch (error: any) {
      // 诊断地址
      console.log(error.data['Recommend'])
      Util.assertAsString(error.message)
      throw new GetVideoPlayerException(error, error.msessage)
    }
  }

  //5.媒体上传完成之后，可以获取媒体播放信息进行播放
  //通过播放凭证播放
  static async getPlayAuth(ctx: Context): Promise<any> {
    if (!ctx.request.body.uploadVideoId) {
      //   console.log(ctx.request.body)
      throw new ParameterException('', 'uploadVideId不能为空！')
    }

    let uploadVideoId = ctx.request.body.uploadVideoId

    try {
      let getVideoPlayAuthRequest = new $vod20170321.GetVideoPlayAuthRequest({
        videoId: uploadVideoId
      })

      let client = Client.createClient(
        process.env['ALIBABA_CLOUD_ACCESS_KEY_ID'] as string,
        process.env['ALIBABA_CLOUD_ACCESS_KEY_SECRET'] as string
      )

      let getVideoPlayAuthReponse = await client.getVideoPlayAuth(
        getVideoPlayAuthRequest
      )
      console.log(getVideoPlayAuthReponse)
      response.success(ctx, getVideoPlayAuthReponse.body, '获取播放凭证成功！')
    } catch (error: any) {
      // 诊断地址
      console.log(error.data['Recommend'])
      Util.assertAsString(error.message)
      throw new GetVideoPlayerException(error, error.msessage, 404)
    }
  }
}

export default Client

Client.main(process.argv.slice(2))
